package com.ndp.fb.walle.business.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.ndp.fb.enums.ErrorType;
import com.ndp.fb.exception.BusinessException;
import com.ndp.fb.model.business.bo.result.UserAudienceTemplateBo;
import com.ndp.fb.model.business.vo.cache.result.PublishCache;
import com.ndp.fb.model.business.vo.cache.result.UserAudienceTemplateCache;
import com.ndp.fb.rdb.api.UserAudienceTemplateLogRdbService;
import com.ndp.fb.rdb.api.UserAudienceTemplateRdbService;
import com.ndp.fb.rdb.model.UserAudienceTemplate;
import com.ndp.fb.rdb.model.UserAudienceTemplateLog;
import com.ndp.fb.redis.api.RedisClient;
import com.ndp.fb.walle.business.CacheService;
import com.ndp.fb.walle.business.UserAudienceTemplateService;
import com.ndp.fb.walle.model.vo.useraudiencetemplate.param.UserAudienceTemplateVoParam;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * Created by Sisi on 15-1-20.
 */
@Component
public class UserAudienceTemplateServiceImpl implements UserAudienceTemplateService {
    private final org.slf4j.Logger LOG = LoggerFactory.getLogger(getClass());
    @Reference
    private UserAudienceTemplateRdbService userAudienceTemplateRdbService;

    @Autowired
    private CacheService cacheService;
    
    @Autowired
    private RedisClient redisClient;
    
    @Reference
    private UserAudienceTemplateLogRdbService userAudienceTemplateLogRdbService;



    @Override
    public UserAudienceTemplateCache buildUserAudienceTemplateCache(String userId,
                                                                    Long companyId, Long connectionObjectId, Long productConfigurationId) {
        UserAudienceTemplateCache userAudienceTemplateCache = new UserAudienceTemplateCache();
        userAudienceTemplateCache.setOrgId(companyId);
        userAudienceTemplateCache.setFbConnectionObjectId(connectionObjectId);
        userAudienceTemplateCache.setProductConfigurationId(productConfigurationId);

        //查询当前登录用户、应用、配置下的用户定位模板
        List<UserAudienceTemplate> userAudienceTemplates = findByCompanyIdAndConfigurationAndConnectionObject(userId, productConfigurationId, connectionObjectId);

        List<UserAudienceTemplateBo> userAudienceTemplateBos = new ArrayList<UserAudienceTemplateBo>();
        List<UserAudienceTemplateBo> recentCreatedTemplateBos = new ArrayList<UserAudienceTemplateBo>();
        List<Long> userAudienceTemplateIds = userAudienceTemplateLogRdbService.findLastSaveAudienceTemplate(userId, productConfigurationId, connectionObjectId, 1, 3);
        UserAudienceTemplateBo userAudienceTemplateBo;
        Map<Long,UserAudienceTemplateBo> map = new HashMap<>();
        for (UserAudienceTemplate userAudienceTemplate : userAudienceTemplates) {
            userAudienceTemplateBo = new UserAudienceTemplateBo(userAudienceTemplate.getId(),
                    userAudienceTemplate.getName(), userAudienceTemplate.getTemplateTargetingSpecs());
            userAudienceTemplateBos.add(userAudienceTemplateBo);
            //最近使用的模板 回头再看存到哪里
            map.put(userAudienceTemplateBo.getId(), userAudienceTemplateBo);
        }
        if(!CollectionUtils.isEmpty(userAudienceTemplateIds)){
        	for(Long id:userAudienceTemplateIds){
                if(map.get(id) != null){
                    recentCreatedTemplateBos.add(map.get(id));
                }
        	}
        }
        userAudienceTemplateCache.setUserAudienceTemplates(userAudienceTemplateBos);
        userAudienceTemplateCache.setRecentCreatedTemplates(recentCreatedTemplateBos);
        return userAudienceTemplateCache;
    }

    @Override
    public Long saveUserAudienceTemplate(String userId, UserAudienceTemplateVoParam userAudienceTemplateVoParam) throws BusinessException {
    	
        //1、校验名称重复与否
    	//这里是否校验当前公司应用下面的模版不能重复
        Long count = countByCompanyConnectionObjectProductCfgAndName(userAudienceTemplateVoParam.getCompanyId(), 
        		userAudienceTemplateVoParam.getFbConnectionObjectId(), userAudienceTemplateVoParam.getProductConfigurationId(),
        		userAudienceTemplateVoParam.getName());
        if (null != count && 0 < count) {
            throw new BusinessException(ErrorType.USERAUDIENCETEMPLATE_NAME_EXIST);
        }
        String key = ""+userAudienceTemplateVoParam.getCompanyId()+userAudienceTemplateVoParam.getFbConnectionObjectId()
        		+userAudienceTemplateVoParam.getProductConfigurationId()+userAudienceTemplateVoParam.getName();
        if(!redisClient.setNx(key, userAudienceTemplateVoParam.getName())){
        	 throw new BusinessException(ErrorType.USERAUDIENCETEMPLATE_NAME_EXIST);
        }
        try {
        	redisClient.expire(key, 5, TimeUnit.MINUTES.name());
            //2、存储用户定位模板
            UserAudienceTemplate userAudienceTemplate = new UserAudienceTemplate();
            userAudienceTemplate.setUserId(userId);
            userAudienceTemplate.setOrgId(userAudienceTemplateVoParam.getCompanyId());
            userAudienceTemplate.setFbConnectionObjectId(userAudienceTemplateVoParam.getFbConnectionObjectId());
            userAudienceTemplate.setProductConfigurationId(userAudienceTemplateVoParam.getProductConfigurationId());
            userAudienceTemplate.setName(userAudienceTemplateVoParam.getName());
            Date createTime = new Date();
            userAudienceTemplate.setCreateTime(createTime);
            userAudienceTemplate.setCreateUtcTime(createTime.getTime());
            userAudienceTemplate.setTemplateTargetingSpecs(userAudienceTemplateVoParam.getTemplateTargetingSpecs());
            Long id = userAudienceTemplateRdbService.saveUserAudienceTemplate(userAudienceTemplate);
            if(id>0){
            	UserAudienceTemplateLog userAudienceTemplateLog = new UserAudienceTemplateLog();
                userAudienceTemplateLog.setFbConnectionObjectId(userAudienceTemplateVoParam.getFbConnectionObjectId());
              	userAudienceTemplateLog.setProductConfId(userAudienceTemplateVoParam.getProductConfigurationId());
              	userAudienceTemplateLog.setUpdatedTime(new Date());
              	userAudienceTemplateLog.setUserAudienceTemplateId(id);
              	userAudienceTemplateLog.setUserId(userId);
              	this.saveUserAudiceTemplateLog(userAudienceTemplateLog);
            }
            
            //3、将新生成的用户定位模板放入缓存当中
            String cacheId = userAudienceTemplateVoParam.getCacheId();
            PublishCache cache = cacheService.fetch(cacheId);
            UserAudienceTemplateCache userAudienceTemplateCache = buildUserAudienceTemplateCache(userId,
                    userAudienceTemplateVoParam.getCompanyId(), userAudienceTemplateVoParam.getFbConnectionObjectId(),
                    userAudienceTemplateVoParam.getProductConfigurationId());

            cache.setUserAudienceTemplate(userAudienceTemplateCache);
            cacheService.update(cacheId, cache);
            return id;
		} catch (Exception e) {
			LOG.error(e.getMessage(),e);
		}finally{
			redisClient.delete(key);
		}
        throw new BusinessException(ErrorType.USERAUDIENCETEMPLATE_NAME_EXIST);
    }

	/** 
	 * @discription
	 * @author giser.yang       
	 * 创建时间 2015年7月8日 下午2:38:28      
	 * @param userId
	 * @param productConfigurationId
	 * @param fbConnectionObjectId
	 * @return     
	 * @see com.ndp.fb.walle.business.UserAudienceTemplateService#(java.lang.String, java.lang.Long, java.lang.Long)
	 */  
	    
	@Override
	public List<UserAudienceTemplate> findByCompanyIdAndConfigurationAndConnectionObject(
			String userId, Long productConfigurationId,
			Long fbConnectionObjectId) {
		return userAudienceTemplateRdbService.findByCompanyIdAndConfigurationAndConnectionObject(userId, productConfigurationId, fbConnectionObjectId);
	}

	/** 
	 * @discription
	 * @author giser.yang       
	 * 创建时间 2015年7月8日 下午3:06:16      
	 * @param companyId
	 * @param fbConnectionObjectId
	 * @param productCfgId
	 * @param name
	 * @return     
	 * @see com.ndp.fb.walle.business.UserAudienceTemplateService#countByCompanyConnectionObjectProductCfgAndName(java.lang.Long, java.lang.Long, java.lang.Long, java.lang.String)     
	 */  
	    
	@Override
	public Long countByCompanyConnectionObjectProductCfgAndName(Long companyId,
			Long fbConnectionObjectId, Long productCfgId, String name) {
		return userAudienceTemplateRdbService.countByCompanyConnectionObjectProductCfgAndName(companyId, fbConnectionObjectId, productCfgId, name);
	}

	/** 
	 * @discription
	 * @author giser.yang       
	 * 创建时间 2015年7月9日 下午12:07:33      
	 * @param userAudienceTemplateLog
	 * @return     
	 * @see com.ndp.fb.walle.business.UserAudienceTemplateService#saveUserAudiceTemplateLog(com.ndp.fb.rdb.model.UserAudienceTemplateLog)     
	 */  
	    
	@Override
	public Long saveUserAudiceTemplateLog(
			UserAudienceTemplateLog userAudienceTemplateLog) {
		return userAudienceTemplateLogRdbService.saveUserAudienceTemplateLog(userAudienceTemplateLog);
	}
}
